
public class KohonenLayer extends NeuronLayer {
	
	public KohonenLayer(Integer neuronsNum, int weightsNum) {
		super(neuronsNum,NeuronLayer.KOHONEN,weightsNum);
	}

	private int getNearestNeuronIndex(NeuronLayer input) {
		float min = 1000;
		float tmp;
		int result = -1;
		for(int i=0;i<neurons.size();i++) {
			tmp = ((KohonenNeuron)neurons.get(i)).countDistance(input);
			//System.out.println("nearest neuron searching: "+i+" distance: "+tmp);
			if(tmp<min) {
				min = tmp;
				result = i;
			}
		}
		System.out.println("nearest neuron: "+result+" with weights: "+neurons.get(result).getWeights()+" and distance: "+((KohonenNeuron)neurons.get(result)).countDistance(input));
		return result;
	}
	
	public void learn(NeuronLayer input) {
		System.out.println("kohonenLayer::learn");
		int nearest = getNearestNeuronIndex(input);
		System.out.println("nearest neuron: "+nearest);
		for(int i=0;i<neurons.size();i++) {
			System.out.println("learning layer neuron: "+i+" with neighbourhood: "+KohonenNeuron.countNeighbourhood(i, nearest, (int)Math.floor(Math.sqrt(neurons.size()))));
			((KohonenNeuron)neurons.get(i)).learn(input, KohonenNeuron.countNeighbourhood(i, nearest, (int)Math.floor(Math.sqrt(neurons.size()))));	
		}
	}
	
	public void normalizeForWidrow() {
		int maxIndex=0;
		Float max = -100.0f;
		for(int i=0; i<this.neurons.size();i++) {
			Neuron n = this.neurons.get(i);
			if(n.getOutput()>max) {
				max = n.getOutput();
				maxIndex = i;
			}
		}
		for(int i=0; i<this.neurons.size();i++) {
			Neuron n = this.neurons.get(i);
			if(i==maxIndex) {
				n.output = 1.0f;
			} else {
				n.output = 0.0f;
			}
		}
	}
	
}
